package com.binary.util;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.net.SocketTimeoutException;
import java.nio.charset.Charset;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.binary.constant.ConstantFactory;
import com.binary.entity.FacadeFactory;
import com.binary.xml.Body;
import com.binary.xml.Document;
import com.binary.xml.Response;

/**
 * @author c_danyanxin
 * @date 2018年8月9日 按照外网出单项目组的开发形式开发；
 */
public class HttpClientSendHelper {

	private static final Logger logger = LoggerFactory
			.getLogger(HttpClientSendHelper.class);

	enum Setting {
		DEFAULT(60, 30, "UTF-8", "application/json"), DEFAULTOTHER(60, 30,
				"UTF-8", "text/plain");
		int socketTimeout;
		int connectTimeout;
		String charset;
		String contentType;

		/**
		 * @param socketTimeout
		 * @param connectTimeout
		 * @param charset
		 * @param contentType
		 */
		private Setting(int socketTimeout, int connectTimeout, String charset,
				String contentType) {
			this.socketTimeout = socketTimeout;
			this.connectTimeout = connectTimeout;
			this.charset = charset;
			this.contentType = contentType;
		}
	}
	/**
	 * 返回结果进行封装
	 * @param response
	 * @param esult
	 */
	public static void convert(Response response,FacadeFactory<Body> esult){
		Body body = response.getBody();
		if(body==null){
			esult.setErrorCode(ConstantFactory.ERROR);
			esult.setErrorMsg("系统繁忙，请稍后重试");
			
		}else{
			if(!"0000".equals(body.getResultCode())){//假设 0000为成功调用，其他为错误
				esult.setErrorCode(body.getResultCode());
				esult.setErrorMsg(body.getResultMsg());
				esult.setBody(body);
			}else{
				esult.setErrorCode(ConstantFactory.SUCCESS);
				esult.setBody(body);
			}
		}
	}
	/**
	 * 得到相应的返回response xml报文转为POJO
	 * @param responseXml
	 * @return
	 */
	public static Response getResponseBodyFromXml(String responseXml){
		Response response = new Response();
		if(responseXml==null||responseXml.equals("")){
			return response;
		}
		try {
			Document document = EndPointServiceHelper.xml2Obj(responseXml);
			response = document.getResponse();
		} catch (Exception e) {
			logger.info("解析xml出错，请查看报文"+responseXml);
		}
		return response;
		
	}
	/**
	 * 调用公共方法
	 * 
	 * @param url
	 * @param requestXml
	 * @param isJsonRequest
	 * @return
	 */
	public static String postXmlOrJson(String url, String requestXml,
			boolean isJsonRequest) throws Exception {
		String response = "";
		
		try {
			long start = System.currentTimeMillis();
			response = post(url.trim(), requestXml, isJsonRequest);
			long end = System.currentTimeMillis();
			logger.info("调用地址 " + url + " 接口耗时 :" + (end - start));

		} catch (Exception e) {
			if (e instanceof ConnectionPoolTimeoutException
					|| e instanceof SocketTimeoutException) {
				logger.error("调用核心接口地址：" + url + " 延时");
			} else {
				logger.error("调用核心接口失败");
			}
			 throw e;
		}
		return response;
	}

	/**
	 * post请求
	 * @param trim
	 * @param requestXml
	 * @return
	 */
	private static String post(String url, String requestXml,
			boolean isJsonRequest) throws Exception {
		CloseableHttpClient client = HttpClients.createDefault();
		String result = "";
		// 1.StringEntity
		try {
			StringEntity stringEntity = null;
			int connectTime = Setting.DEFAULT.connectTimeout * 1000;
			int socketTime = Setting.DEFAULT.socketTimeout * 1000;
			if (isJsonRequest) {
				stringEntity = new StringEntity(requestXml,
						Charset.forName(Setting.DEFAULT.charset));
				stringEntity.setContentType(Setting.DEFAULT.contentType);
			} else {
				stringEntity = new StringEntity(requestXml,
						Charset.forName(Setting.DEFAULTOTHER.charset));
				stringEntity.setContentType(Setting.DEFAULTOTHER.contentType);

			}
			HttpPost post = new HttpPost(url);
			post.setConfig(RequestConfig.custom()
					.setConnectTimeout(connectTime)
					.setSocketTimeout(socketTime).build());
			post.setEntity(stringEntity);
			CloseableHttpResponse response = client.execute(post);
			InputStream in = response.getEntity().getContent();
			Reader reader = new InputStreamReader(in, "UTF-8");
			StringWriter stringWriter = new StringWriter();
			int len = 0;
			char[] buf = new char[1024];
			while ((len = reader.read(buf)) != -1) {
				stringWriter.write(buf, 0, len);
			}
			reader.close();
			stringWriter.flush();
			stringWriter.close();
			response.close();
			result = stringWriter.toString();
		} catch (Exception e) {
			logger.error("调用接口 --------error:" + e.getMessage(), e);
			throw e;
		} finally {
			if (client != null) {
				client.close();
			}
		}
		return result;
	}
}
